创建一个任务管理 API
在本教程中,我们将使用 Node.js 和 Express.js 框架来创建一个简单的任务管理 API。这个 API 将允许用户创建、读取、更新和删除任务。我们将涵盖从环境搭建到 API 设计和实现的整个过程。
1. 环境搭建
1.1 安装 Node.js 和 npm
首先,确保你已经安装了 Node.js 和 npm。你可以通过以下命令检查它们的版本:
node -v
npm -v
如果没有安装,你可以从 Node.js 官网 下载并安装。
1.2 使用 nvm 管理 Node.js 版本
为了方便管理 Node.js 版本,建议安装 nvm(Node Version Manager)。你可以通过以下命令安装 nvm:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
安装完成后,你可以使用以下命令安装和切换 Node.js 版本:
nvm install 14
nvm use 14
2. 创建第一个 Node.js 应用
2.1 初始化项目
创建一个新的项目目录并初始化 npm:
mkdir task-manager-api
cd task-manager-api
npm init -y
2.2 安装 Express.js
Express.js 是一个流行的 Node.js 框架,用于构建 Web 应用程序和 API。我们可以通过以下命令安装它:
npm install express
2.3 创建第一个 Express 应用
在项目根目录下创建一个 index.js 文件,并添加以下代码:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello, Task Manager API!');
});
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
运行应用:
node index.js
打开浏览器并访问 http://localhost:3000,你应该会看到 "Hello, Task Manager API!" 的消息。
3. 模块系统
3.1 CommonJS 模块
在 Node.js 中,默认使用 CommonJS 模块系统。你可以通过 require 和 module.exports 来导入和导出模块。
例如,创建一个 utils.js 文件:
// utils.js
function add(a, b) {
return a + b;
}
module.exports = { add };
然后在 index.js 中使用它:
const { add } = require('./utils');
console.log(add(2, 3)); // 输出 5
3.2 ES Modules
从 Node.js 12 开始,你可以使用 ES Modules。你可以在 package.json 中添加 "type": "module",然后使用 import 和 export 语法。
例如,修改 utils.js:
// utils.js
export function add(a, b) {
return a + b;
}
然后在 index.js 中使用它:
import { add } from './utils.js';
console.log(add(2, 3)); // 输出 5
4. 包管理器
4.1 npm
npm 是 Node.js 的默认包管理器。你可以使用 npm install 安装依赖,使用 npm start 运行脚本。
4.2 yarn
yarn 是另一个流行的包管理器,它提供了更快的安装速度和更好的依赖管理。你可以通过以下命令安装 yarn:
npm install -g yarn
然后使用 yarn add 安装依赖,使用 yarn start 运行脚本。
5. 事件循环和异步编程
5.1 事件循环
Node.js 是单线程的,但它通过事件循环来处理异步操作。事件循环允许 Node.js 执行非阻塞 I/O 操作。
5.2 异步编程
Node.js 提供了多种异步编程方式:
- 回调函数:传统的异步编程方式。
- Promise:更现代的异步编程方式。
- async/await:基于 Promise 的语法糖,使异步代码看起来像同步代码。
例如,使用 setTimeout 模拟异步操作:
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function asyncFunction() {
console.log('Start');
await delay(2000);
console.log('End');
}
asyncFunction();
6. 流和缓冲区
6.1 流
流是 Node.js 中处理大文件或数据流的机制。流可以是可读的、可写的或双工的。
例如,使用 fs 模块创建一个可读流:
const fs = require('fs');
const readStream = fs.createReadStream('file.txt');
readStream.on('data', (chunk) => {
console.log(`Received ${chunk.length} bytes of data.`);
});
readStream.on('end', () => {
console.log('Finished reading file.');
});
6.2 缓冲区
缓冲区是 Node.js 中处理二进制数据的机制。你可以使用 Buffer 类来创建和操作缓冲区。
例如,创建一个缓冲区并写入数据:
const buffer = Buffer.from('Hello, Node.js!');
console.log(buffer.toString()); // 输出 "Hello, Node.js!"
7. 文件系统操作
7.1 读取文件
使用 fs 模块读取文件:
const fs = require('fs');
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
7.2 写入文件
使用 fs 模块写入文件:
const fs = require('fs');
fs.writeFile('file.txt', 'Hello, Node.js!', (err) => {
if (err) throw err;
console.log('File written successfully.');
});
8. 网络编程
8.1 HTTP 模块
Node.js 提供了 http 模块来创建 HTTP 服务器和客户端。
例如,创建一个简单的 HTTP 服务器:
const http = require('http');
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello, World!\n');
});
server.listen(3000, () => {
console.log('Server running at http://localhost:3000/');
});
8.2 HTTPS 模块
Node.js 还提供了 https 模块来创建 HTTPS 服务器。你需要提供 SSL 证书和密钥。
9. Express.js 框架入门
9.1 安装 Express.js
我们已经在前面的步骤中安装了 Express.js。
9.2 创建一个简单的 Express 应用
修改 index.js 文件:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello, Task Manager API!');
});
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
10. 路由和中间件
10.1 路由
路由是定义如何响应客户端请求的机制。你可以使用 app.get、app.post 等方法来定义路由。
例如,定义一个 /tasks 路由:
app.get('/tasks', (req, res) => {
res.send('List of tasks');
});
10.2 中间件
中间件是处理请求和响应的函数。你可以使用 app.use 来添加中间件。
例如,添加一个日志中间件:
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
11. 模板引擎
11.1 EJS
EJS 是一个简单的模板引擎,允许你在 HTML 中嵌入 JavaScript 代码。
安装 EJS:
npm install ejs
配置 EJS:
app.set('view engine', 'ejs');
创建一个 views 目录,并在其中创建一个 index.ejs 文件:
<!DOCTYPE html>
<html>
<head>
<title>Task Manager</title>
</head>
<body>
<h1>Tasks</h1>
<ul>
<% tasks.forEach(task => { %>
<li><%= task %></li>
<% }) %>
</ul>
</body>
</html>
在 index.js 中渲染模板:
app.get('/tasks', (req, res) => {
const tasks = ['Task 1', 'Task 2', 'Task 3'];
res.render('index', { tasks });
});
11.2 Pug
Pug 是另一个流行的模板引擎,使用缩进来定义 HTML 结构。
安装 Pug:
npm install pug
配置 Pug:
app.set('view engine', 'pug');
创建一个 views 目录,并在其中创建一个 index.pug 文件:
doctype html
html
head
title Task Manager
body
h1 Tasks
ul
each task in tasks
li= task
在 index.js 中渲染模板:
app.get('/tasks', (req, res) => {
const tasks = ['Task 1', 'Task 2', 'Task 3'];
res.render('index', { tasks });
});
12. RESTful API 设计和实现
12.1 设计 RESTful API
RESTful API 遵循 REST 架构风格,使用 HTTP 方法(GET、POST、PUT、DELETE)来操作资源。
例如,设计一个任务管理 API:
GET /tasks:获取所有任务GET /tasks/:id:获取单个任务POST /tasks:创建新任务PUT /tasks/:id:更新任务DELETE /tasks/:id:删除任务
12.2 实现 RESTful API
使用 Express.js 实现上述 API:
let tasks = [];
let taskId = 1;
app.use(express.json());
app.get('/tasks', (req, res) => {
res.json(tasks);
});
app.get('/tasks/:id', (req, res) => {
const task = tasks.find(t => t.id === parseInt(req.params.id));
if (!task) return res.status(404).send('Task not found');
res.json(task);
});
app.post('/tasks', (req, res) => {
const task = { id: taskId++, ...req.body };
tasks.push(task);
res.status(201).json(task);
});
app.put('/tasks/:id', (req, res) => {
const task = tasks.find(t => t.id === parseInt(req.params.id));
if (!task) return res.status(404).send('Task not found');
task.title = req.body.title;
task.completed = req.body.completed;
res.json(task);
});
app.delete('/tasks/:id', (req, res) => {
tasks = tasks.filter(t => t.id !== parseInt(req.params.id));
res.status(204).send();
});
13. 身份认证和授权
13.1 基本认证
使用 Express.js 实现基本认证:
app.use((req, res, next) => {
const auth = { login: 'admin', password: 'password' };
const b64auth = (req.headers.authorization || '').split(' ')[1] || '';
const [login, password] = Buffer.from(b64auth, 'base64').toString().split(':');
if (login && password && login === auth.login && password === auth.password) {
return next();
}
res.set('WWW-Authenticate', 'Basic realm="401"');
res.status(401).send('Authentication required.');
});
13.2 JWT 认证
使用 JSON Web Token (JWT) 实现认证:
安装 jsonwebtoken:
npm install jsonwebtoken
实现 JWT 认证:
const jwt = require('jsonwebtoken');
const secretKey = 'your-secret-key';
app.post('/login', (req, res) => {
const { username, password } = req.body;
if (username === 'admin' && password === 'password') {
const token = jwt.sign({ username }, secretKey, { expiresIn: '1h' });
res.json({ token });
} else {
res.status(401).send('Invalid credentials');
}
});
app.use((req, res, next) => {
const token = req.headers['authorization'];
if (!token) return res.status(403).send('Token required');
jwt.verify(token, secretKey, (err, decoded) => {
if (err) return res.status(401).send('Invalid token');
req.user = decoded;
next();
});
});
14. SQL 数据库
14.1 MySQL
安装 mysql2 包:
npm install mysql2
连接到 MySQL 数据库:
const mysql = require('mysql2');
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'task_manager'
});
connection.connect((err) => {
if (err) throw err;
console.log('Connected to MySQL database');
});
14.2 PostgreSQL
安装 pg 包:
npm install pg
连接到 PostgreSQL 数据库:
const { Client } = require('pg');
const client = new Client({
user: 'root',
host: 'localhost',
database: 'task_manager',
password: 'password',
port: 5432,
});
client.connect((err) => {
if (err) throw err;
console.log('Connected to PostgreSQL database');
});
15. NoSQL 数据库
15.1 MongoDB
安装 mongodb 包:
npm install mongodb
连接到 MongoDB 数据库:
const { MongoClient } = require('mongodb');
const uri = 'mongodb://localhost:27017';
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });
client.connect((err) => {
if (err) throw err;
console.log('Connected to MongoDB database');
});
16. ORM 和 ODM
16.1 Sequelize
Sequelize 是一个流行的 ORM,支持多种 SQL 数据库。
安装 Sequelize 和 MySQL 驱动:
npm install sequelize mysql2
初始化 Sequelize:
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('task_manager', '